package scuts.core;


import scuts.core.types.Ordering;
import scuts.core.types.LazyIterator;
import scuts.core.Fold;
using scuts.core.Fold;

class MinimumByIterator 
{

  public static function minimumBy <T>(it:Iterator<T>, f:T->T->Ordering):T 
  {
    if (!it.hasNext()) throw "cannot find maximum on empty list";
    
    var compare = function (cur, max) {
      return switch (f(cur, max)) {
        case LT: cur;
        case EQ: max;
        case GT: max;
      }
    }
    
    return it.foldl(compare, it.next());
  }
  
}

class MinimumByIterable 
{
  public static inline function minimumBy <T>(it:Iterable<T>, f:T->T->Ordering):T 
  {
    return MinimumByIterator.minimumBy(it.iterator(), f);
  }
}

class MinimumByLazyIterator
{
  public static inline function minimumBy <T>(it:LazyIterator<T>, f:T->T->Ordering):T 
  {
    return MinimumByIterator.minimumBy(it(), f);
  }
}